import React, {Component} from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import FileSaver from 'file-saver';

export default class DataBlock extends Component {
  static propTypes = {
    data: PropTypes.object,
    onChange: PropTypes.func,
  }

  static defaultProps = {
    cols: 16
  }

  state = {data: this.props.data || new Buffer(), loading: false};

  handleChange = () => {
    this.props.onChange && this.props.onChange(this.state.data);
  }

  displayByte(byte) {
    if (typeof(byte) === 'number') {
      return (byte < 0x10 ? '0' : '') + byte.toString(16).toUpperCase();
    } else {
      return null;
    }
  }

  selectFile = e => {
    this.uploader.click();
  }

  openFile = (event) => {
    let file = event.target.files[0];
    if (file) {
      if (file.size > 1024*1024) {
        alert('<%= UIText.FileTooBig %>')
        return;
      }
      this.setState({loading: true}, () => {
        let reader = new FileReader();
        reader.onload = e => {
          this.setState({data: new Buffer(e.target.result), loading: false}, this.handleChange);
        };
        reader.readAsArrayBuffer(file);
      });
    }
  }

  saveFile = () => {
    let blob = new Blob([this.state.data], {type: "application/octet-stream"});
    FileSaver.saveAs(blob, 'data block.txt');
  }

  componentWillReceiveProps(nextProps) {
    this.setState({data: nextProps.data || []});
  }

  render() {
    if (this.state.loading) {
      return <div className="scroll-view data-block"><i className="fa fa-spinner" /></div>;
    }
    const cols = this.props.cols;
    let data = this.state.data;
    return <div className="scroll-view data-block">
      <div className="toobar">
        <input ref={elem => this.uploader = elem} type="file" style={{display: 'none'}} onChange={this.openFile} />
        <a title="open file" onClick={this.selectFile}><i className="fa fa-file-text-o" /></a>
        <a title="save file" onClick={this.saveFile}><i className="fa fa-save" /></a>
        <span>|{this.state.data.length} bytes</span>
      </div>
      <table className="table">
        <tbody>
          {_.range(Math.ceil(data.length / cols)).map(row =>
            <tr key={row}>
              {_.range(cols).map(col => <td key={col}>{this.displayByte(data[row*cols + col])}</td>)}
            </tr>
          )}
        </tbody>
      </table>
    </div>;
  }
}
